﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GraphAlgorithm;

namespace GraphTest
{
	public class Program
	{
		/// <summary>
		/// Véletlen generátor.
		/// </summary>
		static Random rnd = new Random();

		/// <summary>
		/// Véletlen gráf létrehozása.
		/// </summary>
		/// <param name="vertex">A csomópontok száma.</param>
		/// <param name="colors">A használható színek száma.</param>
		/// <param name="PColorAccepted">Ekkora eséllyel fogad el egy csomópont egy színt.</param>
		/// <param name="PEdge">Két pont közötti él valószínűsége.</param>
		/// <param name="wMin">Pontok legkisebb súlya.</param>
		/// <param name="wMax">Pontok legnagyobb súlya</param>
		/// <returns>A feltételeknek megfelelő gráf.</returns>
		public static Graph CreateRandomGraph( int vertex, int colors, double PColorAccepted, double PEdge, int wMin, int wMax )
		{
			// Pontok létrehozása
			Graph G = new Graph();
			for( int i = 0; i < vertex; i++ )
			{
				G.AddVertex( 1, rnd.Next( wMin, wMax + 1 ) );
			}

			// Színek létrehozása
			G.AddColor( colors );

			// Színek hozzárendelés az pontokhoz.
			for( int i = 0; i < vertex; i++ )
			{
				// Véletlen színek.
				for( int j = 0; j < colors; j++ )
				{
					if( rnd.NextDouble() < PColorAccepted )
					{
						G.AddColorToVertex( i, j );
					}
				}

				// Legalább egy szín minden ponthoz
				if( G.GetVertexColorCount( i ) == 0 )
				{
					G.AddColorToVertex( i, rnd.Next( colors ) );
				}
			}

			// Élek létrehozása
			for( int i = 0; i < vertex; i++ )
			{
				for( int j = i + 1; j < vertex; j++ )
				{
					if( rnd.NextDouble() < PEdge )
					{
						G.AddEdge( i, j );
					}
				}
			}

			return G;
		}

		/// <summary>
		/// A felesleges éleket törlésével és a színlisták megszüntetésével előállított gráfot adja vissza.
		/// </summary>
		/// <param name="G">Az eredeti gráf.</param>
		/// <returns> A felesleges éleket törlésével és a színlisták megszüntetésével előállított gráfot adja vissza.</returns>
		public static Graph CorrectedGraph( Graph G )
		{
			Graph G2 = new Graph();
			G2.AddVertex( G.VertexCount );

			for( int i = 0; i < G.VertexCount; i++ )
			{
				for( int j = i + 1; j < G.VertexCount; j++ )
				{
					if( G.HaveEdge( i, j ) && G.HaveCommonColor( i, j ) )
					{
						G2.AddEdge( i, j );
					}
				}
			}

			return G2;
		}

		/// <summary>
		/// A gráf statisztikai adatait adja vissza. (Max fok, átl fok, átl színmetszet)
		/// </summary>
		/// <param name="G"></param>
		/// <returns></returns>
		public static int[] MeasureGraph( Graph G )
		{
			int maxDegree;
			int avgDegree;
			int avgIntersect;

			Graph G2 = CorrectedGraph( G );

			List<int> dList = new List<int>();
			List<int> iList = new List<int>();
			for( int i = 0; i < G2.VertexCount; i++ )
			{
				dList.Add( G2.Degree( i ) );
			}

			avgDegree = (int)( Math.Round( dList.Average() ) );
			maxDegree = dList.Max();

			for( int i = 0; i < G.VertexCount; i++ )
			{
				for( int j = i + 1; j < G.VertexCount; j++ )
				{
					iList.Add( G.IntersectSize( i, j ) );
				}
			}

			avgIntersect = (int)( Math.Round( iList.Average() ) );

			return new int[] { maxDegree, avgDegree, avgIntersect };
		}

		/// <summary>
		/// Kipróbáló program.
		/// </summary>
		/// <param name="args">Parancssori paraméterek.</param>
		static void Main( string[] args )
		{
			Graph G = CreateRandomGraph( 5, 3, 0.8, 0.7, 1, 5 );
			G.EqualizeColorWeight();
			G.Print();
			Console.ReadKey();

			RandomColorAlgorithm.Result result = RandomColorAlgorithm.DoColoring( G, 10000 );
			if( result.IsSucceded )
			{
				G.Print();
				Console.WriteLine( "Coloring succeded" );
			}
			else
			{
				Console.WriteLine( "Conflict: " + result.FirstConflict.Begin + " - " + result.FirstConflict.End );
				Console.WriteLine( "Coloring failed" );
			}
			Console.ReadKey();

		}
	}
}
